﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;

namespace JKF.Substructure
{
    public static class CacheManage
    {
        /// <summary>
        /// 判断缓存是否存在
        /// </summary>
        /// <param name="name">缓存名称</param>
        /// <returns></returns>
        public  static bool HadCache(string name)
        {
            //return false;
            return HttpContext.Current.Cache[name] != null;
        }

        /// <summary>
        /// 取得缓存
        /// </summary>
        /// <param name="name">缓存名</param>
        /// <returns></returns>
        public static object GetCache(string name)
        {
            return HttpContext.Current.Cache[name];
        }

        /// <summary>
        /// 取缓存 
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static TResult GetCache<TResult>(string key) where TResult :class 
        {
            var obj = CacheManage.GetCache(key);
            if (obj == null)
            {
                throw new NullReferenceException("缓存不存在");
            }
            return obj as TResult;
        }

        /// <summary>
        /// 新增加缓存
        /// </summary>
        /// <param name="name">缓存名称</param>
        /// <param name="obj">需要缓存的对象</param>
        /// <param name="senconds">缓存时间(以时间分为单位,如果传入,0:表示永久缓存,-1:以文件作为目录缓存)]</param>
        /// <param name="isCover">是否忽略已有缓存(true:表示忽略已存在的同名缓存并写入新的对象,false:表示如果存在则不需要再次覆盖)</param>
        /// <param name="mapPath">当目录缓存时,传入文件web目录地址(如:~/web/login.aspx)</param>
        /// <returns>缓存对象</returns>
        public static object AddCache(string name,object obj,double senconds,bool isCover,string mapPath)
        {
            if(!HadCache(name) ||(HadCache(name) && isCover))
            {
                if (senconds > 0)
                {
                    HttpContext.Current.Cache.Insert(name, obj, null,DateTime.Now.AddSeconds(senconds),
                                                     TimeSpan.Zero);
                }
                else if (senconds == 0)
                {
                    HttpContext.Current.Cache[name] = obj;
                }
                else
                {
                    if(string.IsNullOrEmpty(mapPath))
                        throw new Exception("基于文件缓存时,文件路径必须填写");
                    if (System.IO.File.Exists(HttpContext.Current.Server.MapPath(mapPath)))
                    {
                        HttpContext.Current.Cache.Insert(name, obj,
                                                         new System.Web.Caching.CacheDependency(
                                                             HttpContext.Current.Server.MapPath(mapPath)));
                    }
                    else
                    {
                        throw new Exception("文件路径不存在该文件");
                    }
                }
            }

            return GetCache(name);
        }

        /// <summary>
        /// 新增缓存
        /// </summary>
        /// <param name="name">缓存名</param>
        /// <param name="obj">需要缓存的对象</param>
        /// <returns></returns>
        public static object AddCache(string name,object obj)
        {
            return AddCache(name, obj, 0, true, string.Empty);
        }

        /// <summary>
        /// 新增时间缓存
        /// </summary>
        /// <param name="name">缓存名称</param>
        /// <param name="obj">对象</param>
        /// <param name="senconds">时长(分钟)[正整数]</param>
        /// <returns></returns>
        public static object AddCache(string name, object obj, double senconds)
        {
            if (senconds > 0)
                return AddCache(name, obj, senconds, true, string.Empty);
            else
                throw new Exception("缓存时间不能小于0");
        }

        /// <summary>
        /// 新增基于文件缓存
        /// </summary>
        /// <param name="name">缓存名称</param>
        /// <param name="obj">对象</param>
        /// <param name="mapPath">文件路径</param>
        /// <returns></returns>
        public static object AddCahe(string name,object obj,string mapPath)
        {
           return AddCache(name, obj, -1, true, mapPath);
        }
       

        /// <summary>
        /// 删除缓存[支持结尾*表示以什么开始的缓存]
        /// </summary>
        /// <param name="name">缓存名[为空则清空所有缓存]</param>
        public static void Remove(string name)
        {
            if (!string.IsNullOrEmpty(name))
            {
                if(name=="*")
                {
                    foreach (DictionaryEntry caches in HttpContext.Current.Cache)
                    {
                        HttpContext.Current.Cache.Remove(caches.Key.ToString());
                    }
                    return;
                }

                if(name.EndsWith("*"))
                {
                    string n = name.TrimEnd('*');
                    foreach (DictionaryEntry caches in HttpContext.Current.Cache)
                    {
                        if (caches.Key.ToString().StartsWith(n))
                        HttpContext.Current.Cache.Remove(caches.Key.ToString());
                    }
                }
                else
                {
                    HttpContext.Current.Cache.Remove(name); 
                }
               
            }
            else
            {
                foreach (DictionaryEntry caches in HttpContext.Current.Cache)
                {
                    HttpContext.Current.Cache.Remove(caches.Key.ToString());
                }
            }
        }

        /// <summary>
        /// 清除体验项所有缓存
        /// </summary>
        public static void ClearExamItem()
        {
            Remove("*");
            
        }
    }
}
